package com.dukk.gis.tools.extensions.projections;

import com.dukk.gis.tools.GeoTool;
import org.locationtech.jts.geom.*;
import org.locationtech.proj4j.ProjCoordinate;
import org.locationtech.proj4j.proj.EquidistantAzimuthalProjection;

/**
 * 方位等距投影
 *
 * https://en.wikipedia.org/wiki/Azimuthal_equidistant_projection
 */
public class EquidistantAzimuthalProjectionTool {

    EquidistantAzimuthalProjection equidistantAzimuthalProjection = new EquidistantAzimuthalProjection();

    GeometryFactory geometryFactory = GeoTool.getGeoFactory();

    public Coordinate project(Coordinate coordinate){
        ProjCoordinate srcPro = new ProjCoordinate();
        srcPro.setValue(coordinate.x, coordinate.y, coordinate.z);
        ProjCoordinate tarPro = new ProjCoordinate();
        this.equidistantAzimuthalProjection.project(srcPro, tarPro);
        return new Coordinate(tarPro.x, tarPro.y, tarPro.z);
    }

    public Coordinate inverseProject(Coordinate coordinate){
        ProjCoordinate srcPro = new ProjCoordinate();
        srcPro.setValue(coordinate.x, coordinate.y, coordinate.z);
        ProjCoordinate tarPro = new ProjCoordinate();
        this.equidistantAzimuthalProjection.inverseProject(srcPro, tarPro);
        return new Coordinate(tarPro.x, tarPro.y, tarPro.z);
    }

    public Geometry project(LineString geometry){
        Coordinate coordinates[] = geometry.getCoordinates();
        CoordinateList coordinateList = new CoordinateList();
        for(Coordinate coordinate : coordinates){
            coordinateList.add(project(coordinate));
        }
        return geometryFactory.createLineString(coordinateList.toCoordinateArray());
    }

    public Geometry project(Polygon geometry){
        Coordinate coordinates[] = geometry.getCoordinates();
        CoordinateList coordinateList = new CoordinateList();
        for(Coordinate coordinate : coordinates){
            coordinateList.add(project(coordinate));
        }
        return geometryFactory.createPolygon(coordinateList.toCoordinateArray());
    }

    public Geometry inverseProject(LineString geometry){
        Coordinate coordinates[] = geometry.getCoordinates();
        CoordinateList coordinateList = new CoordinateList();
        for(Coordinate coordinate : coordinates){
            coordinateList.add(inverseProject(coordinate));
        }
        return geometryFactory.createLineString(coordinateList.toCoordinateArray());
    }

    public Geometry inverseProject(Polygon geometry){
        Coordinate coordinates[] = geometry.getCoordinates();
        CoordinateList coordinateList = new CoordinateList();
        for(Coordinate coordinate : coordinates){
            coordinateList.add(inverseProject(coordinate));
        }
        return geometryFactory.createPolygon(coordinateList.toCoordinateArray());
    }

}
